package special_class;

import java.util.Arrays;

/**
 * @author : niu niu
 * @version : 1.0.0
 * @date : 2022/9/23 19:29
 *
 *  字符串的不可变性
 *      当一个字符串对象产生之后，他的内容就无法改变
 *      指的是：字符串的对象内容不能修改，而不是引用
 *          "不可变"   str = ？ 可变
 *
 *      为什么唯独字符串对象的内容无法修改？？（如何理解字符串对象不可变，是如何做到的？）
 *           private final char value[];
 *           private修饰该属性，将其完全封装，对外没有提供任何获取或修改该value的方法
 *              出了这个类，外部就无法直接操作这个数组，因此不能改。
 *           final 保证字符串对象的线程安全问题，和可变不可变没关系
 *
 *      为什么要设计成不可变？
 *      1. 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.
 *      2. 不可变对象是线程安全的.
 *      3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中
 *
 *
 *       - ///String提供的所有涉及字符串修改的方案，都会产生新的字符串对象，并不会影响原先字符串对象\\\ -
 *       所谓看起来的修改，其实是创建了新的对象
 *
 *  StringBuilder和StringBuffer:
 *      因此在需要反复修改字符串内容的场景下，使用StingBuilder（90%Use 线程不安全，效率高）或StringBuffer（10%Use线程安全，效率低）
 *
 *        注意：String和StringBuilder类不能直接转换。如果要想互相转换，可以采用如下原则:
 *                String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
 *                StringBuilder变为String: 调用toString()方法
 *          由于这两个内容可变，所以有更多的方法：
 *              append（String str）  在尾部追加，相当于String的+=，可以追加：boolean、char、char[]、double、float、int、long、Object、String、StringBuff的变量
 *              charAt(int index)  获取index位置的字符
 *              StringBuffer reverse()  反转字符串
 *              String toString()   将所有字符按照String的方式返回
 *              StringBuffer deleteCharAt(int index)  删除index位置字符
 *              StringBuffer delete(int start, int end)  删除[start, end)区间内的字符
 *              StringBuffer replace(int start, int end, String str)  将[start, end)位置的字符替换为str
 *
 *    String、StringBuffer、StringBuilder的区别？
 *          1.String的内容不可修改，StringBuffer与StringBuilder的内容可以修改.
 *          2.StringBuffer与StringBuilder大部分功能是相似的
 *          3.StringBuffer采用同步处理，效率低，属于线程安全操作；而StringBuilder采用异步处理，效率高，属于线程不安全操
 *
 *          //javac 编译器会将String += 操作优化为 StringBuilder 的append操作
 * 作
 */
public class StringNotChange {

    public static void main(String[] args) {
//        final char[] value = {'q','w','e'};
//        //这里的final指的是 引用的地址不能改！其内容可以修改
//        final char[] value1 = {'q','w'};
//        //java: 无法为最终变量value分配值
////        value = value1;
//        value[0]='a';
//        System.out.println(Arrays.toString(value));

        String str = "abc";
        char[] value  ={'a','b','c'};
        fun(str,value);
        System.out.println(str);
        System.out.println(Arrays.toString(value));
        //String--->StringBuilder
        //法一：构造方法
        StringBuilder stringBuilder = new StringBuilder(str);
        //法二：append方法
        StringBuilder stringBuilder1 = new StringBuilder();
        stringBuilder1.append(str);
        stringBuilder1.append("123");

        //StringBuilder ---> String
        //调用toString方法
        String ret = stringBuilder1.toString();
        System.out.println(ret);


    }

    private static void  fun(String str,char[] value){
        str = "gbc";
        value[0] = 'g';
    }
}
